/*
 * Copyright 2007. Mount Sinai Hospital, Toronto, Canada.
 * 
 * Licensed under the GNU Lesser General Public License, Version 2. You
 * can find a copy of the license at:
 * 
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 * 
 * IN NO EVENT SHALL MOUNT SINAI HOSPITAL BE LIABLE TO ANY PARTY FOR DIRECT, 
 * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST 
 * PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, 
 * EVEN IF MOUNT SINAI HOSPITAL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
 * DAMAGE.
 * 
 * MOUNT SINAI HOSPITAL SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND 
 * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". 
 * MOUNT SINAI HOSPITAL HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, 
 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 
 */
package com.sinai.mshab.widgets;

import java.util.Date;

import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;

/**
 * This widget provides 3 drop downs, one for year, month and day Sometimes it
 * is more convenient to use this over date picker.
 * 
 * @author serge
 * 
 */
public class DropDownDateComponent extends HorizontalPanel {

	/**
	 * The default number of years ahead of the current year.
	 */
	public static final int YEARS_AHEAD_CURRENT = 50;

	/**
	 * The default number of years before the current year.
	 */
	public static final int YEARS_BEFORE_CURRENT = 100;

	/** We need access to our widgets */
	private ListBox year, month, day;

	/**
	 * The current year.
	 */
	private int current_year;

	/**
	 * The date format we'll be using for parsing dates.
	 */
	private static final DateTimeFormat DATE_TIME_FORMAT =
			DateTimeFormat.getFormat("yyyy-MM-dd");

	/**
	 * The months of the year.
	 */
	private String[] months =
			{ "January", "February", "March", "April", "May", "June", "July",
					"August", "September", "October", "November", "December" };

	/**
	 * Creates a new date picker with three dropdowns for year, month and day.
	 */
	public DropDownDateComponent() {

		// creating the year dropdown. The year is by default set to 100 years
		// before the
		// current year and 50 years ahead of the current year.
		year = new ListBox();
		Date date = new Date();
		current_year = date.getYear() + 1900;
		for (int i = current_year - YEARS_BEFORE_CURRENT; i <= current_year
				+ YEARS_AHEAD_CURRENT; i++) {
			year.addItem(i + "");
		}

		// creating the month dropdown
		month = new ListBox();
		for (int i = 0; i < 12; i++) {
			month.addItem(months[i]);
		}

		// creating the days dropdown
		day = new ListBox();
		for (int i = 1; i < 32; i++) {
			day.addItem(i + "");
		}

		add(year);
		add(month);
		add(day);

		// set the drop down date component to the current date.
		setDate(date);
	}

	/**
	 * Sets the widget to show a specific date.
	 * 
	 * @param y
	 *            the new year
	 * @param m
	 *            the new month
	 * @param d
	 *            the new day
	 */
	private void setDate(int y, int m, int d) {

		// get the maximum year
		int minimumYear = Integer.parseInt(year.getItemText(0));
		int diff = y - minimumYear;
		year.setSelectedIndex(diff);
		month.setSelectedIndex(m - 1);
		day.setSelectedIndex(d - 1);
	}

	/**
	 * Sets the date of this {@code DropDownDateComponent} to {@code date}.
	 * 
	 * @param date
	 *            the new date of this {@code DropDownDateComponent}.
	 */
	public void setDate(Date date) {

		// format the date into a format we can work with.
		String formattedDate = DATE_TIME_FORMAT.format(date);

		// parse the integer values out of the date.
		int year = Integer.parseInt(formattedDate.substring(0, 4));
		int month = Integer.parseInt(formattedDate.substring(5, 7));
		int day = Integer.parseInt(formattedDate.substring(8, 10));
		setDate(year, month, day);
	}

	/**
	 * Returns the Date that this {@code DropDownDateComponent} represents.
	 * 
	 * @return the Date that this {@code DropDownDateComponent} represents.
	 */
	public Date getDate() {

		String s_year = year.getValue(year.getSelectedIndex());
		String s_month = "" + (1 + month.getSelectedIndex());
		String s_day = day.getValue(day.getSelectedIndex());

		// inserting 0s in the front of months or days as needed
		if (s_month.length() == 1)
			s_month = "0" + s_month;
		if (s_day.length() == 1)
			s_day = "0" + s_day;

		String final_date = s_year + "-" + s_month + "-" + s_day;
		return DATE_TIME_FORMAT.parse(final_date);
	}

	/**
	 * Sets the range of years that the user can select. The range starts from
	 * minimum (inclusive) and ends at maximum (inclusive).
	 * 
	 * @param minimum
	 *            the furthest year in the past the user can select.
	 * @param maximum
	 *            the furthest year in the future the user can select.
	 */
	public void setYearRange(int minimum, int maximum) {
		year.clear();
		Date d = new Date();
		current_year = d.getYear() + 1900;

		for (int i = minimum; i <= maximum; i++) {
			year.addItem(i + "");
		}
		year.setSelectedIndex(maximum - minimum);
	}
}
